﻿using System.Runtime.InteropServices;

namespace DynamicMouse.Native
{
    /// <summary>
    /// 提供 Win32 鼠标相关 API 的封装
    /// </summary>
    public static partial class Win32MouseApi
    {
        private const string User32 = "user32.dll";

        #region Win32 Constants
        /// <summary>
        /// 获取鼠标速度设置的参数
        /// </summary>
        public const uint SPI_GETMOUSESPEED = 0x0070;

        /// <summary>
        /// 设置鼠标速度的参数
        /// </summary>
        public const uint SPI_SETMOUSESPEED = 0x0071;

        /// <summary>
        /// 获取双击时间间隔的参数
        /// </summary>
        public const uint SPI_GETDOUBLECLICKTIME = 0x0028;

        /// <summary>
        /// 设置双击时间间隔的参数
        /// </summary>
        public const uint SPI_SETDOUBLECLICKTIME = 0x0020;

        /// <summary>
        /// 获取鼠标滚轮滚动行数的参数
        /// </summary>
        public const uint SPI_GETWHEELSCROLLLINES = 0x0068;

        /// <summary>
        /// 设置鼠标滚轮滚动行数的参数
        /// </summary>
        public const uint SPI_SETWHEELSCROLLLINES = 0x0069;

        /// <summary>
        /// 获取鼠标悬停时间的参数
        /// </summary>
        public const uint SPI_GETMOUSEHOVERTIME = 0x0066;

        /// <summary>
        /// 设置鼠标悬停时间的参数
        /// </summary>
        public const uint SPI_SETMOUSEHOVERTIME = 0x0067;

        /// <summary>
        /// 获取鼠标悬停区域宽度的参数
        /// </summary>
        public const uint SPI_GETMOUSEHOVERWIDTH = 0x0062;

        /// <summary>
        /// 设置鼠标悬停区域宽度的参数
        /// </summary>
        public const uint SPI_SETMOUSEHOVERWIDTH = 0x0063;

        /// <summary>
        /// 获取鼠标悬停区域高度的参数
        /// </summary>
        public const uint SPI_GETMOUSEHOVERHEIGHT = 0x0064;

        /// <summary>
        /// 设置鼠标悬停区域高度的参数
        /// </summary>
        public const uint SPI_SETMOUSEHOVERHEIGHT = 0x0065;

        /// <summary>
        /// 获取鼠标轨迹设置的参数
        /// </summary>
        public const uint SPI_GETMOUSETRAILS = 0x005E;

        /// <summary>
        /// 设置鼠标轨迹的参数
        /// </summary>
        public const uint SPI_SETMOUSETRAILS = 0x005D;

        /// <summary>
        /// 获取鼠标加速度设置的参数
        /// </summary>
        public const uint SPI_GETMOUSE = 0x0003;

        /// <summary>
        /// 设置鼠标加速度的参数
        /// </summary>
        public const uint SPI_SETMOUSE = 0x0004;

        /// <summary>
        /// 指示 SystemParametersInfo 函数将更新的设置写入用户配置文件
        /// </summary>
        public const uint SPIF_UPDATEINIFILE = 0x01;

        /// <summary>
        /// 指示 SystemParametersInfo 函数向所有顶级窗口发送 WM_SETTINGCHANGE 消息
        /// </summary>
        public const uint SPIF_SENDCHANGE = 0x02;
        #endregion


        /// <summary>
        /// 获取系统双击时间间隔
        /// </summary>
        [LibraryImport(User32, EntryPoint = "GetDoubleClickTime")]
        internal static partial uint GetDoubleClickTimeNative();

        /// <summary>
        /// 设置系统双击时间间隔
        /// </summary>
        [LibraryImport(User32, EntryPoint = "SetDoubleClickTime")]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static partial bool SetDoubleClickTimeNative(uint uInterval);

        /// <summary>
        /// 包装 GetDoubleClickTimeNative 调用
        /// </summary>
        /// <returns></returns>
        public static uint GetDoubleClickTime() => GetDoubleClickTimeNative();

        /// <summary>
        /// 保证 SetDoubleClickTimeNative 调用
        /// </summary>
        /// <param name="interval"></param>
        /// <returns></returns>
        public static bool SetDoubleClickTime(uint interval) => SetDoubleClickTimeNative(interval);

        //这里需要说明下，每个win32Api如果使用了LibraryImport，就需要再包装一次调用，否则就会提示：必须具有实现部分，因为它具有可访问性修饰符.
        //--------------------------------------------------------------------------------------------//

        /// <summary>
        /// SystemParametersInfo 函数的包装，用于处理整数参数
        /// </summary>
        [LibraryImport(User32, EntryPoint = "SystemParametersInfoW", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static partial bool SystemParametersInfoInt(
            uint uiAction,
            uint uiParam,
            ref int pvParam,
            uint fWinIni);

        /// <summary>
        /// SystemParametersInfo 函数的包装，用于处理指针参数
        /// </summary>
        [LibraryImport(User32, EntryPoint = "SystemParametersInfoW", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static partial bool SystemParametersInfoPtr(
            uint uiAction,
            uint uiParam,
            IntPtr pvParam,
            uint fWinIni);

        /// <summary>
        /// 包装 SystemParametersInfo 调用，处理整数参数
        /// </summary>
        public static bool SystemParametersInfo(uint uiAction, uint uiParam, ref int pvParam, uint fWinIni)
        {
            return SystemParametersInfoInt(uiAction, uiParam, ref pvParam, fWinIni);
        }

        /// <summary>
        /// 包装 SystemParametersInfo 调用，处理指针参数
        /// </summary>
        public static bool SystemParametersInfo(uint uiAction, uint uiParam, IntPtr pvParam, uint fWinIni)
        {
            return SystemParametersInfoPtr(uiAction, uiParam, pvParam, fWinIni);
        }
    }
}
